/*
   Copyright (c) [Year] [name of copyright holder]
   [Software Name] is licensed under Mulan PSL v2.
   You can use this software according to the terms and conditions of the Mulan PSL v2. 
   You may obtain a copy of Mulan PSL v2 at:
            http://license.coscl.org.cn/MulanPSL2 
   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.  
   See the Mulan PSL v2 for more details.  
*/

#ifndef JIAJIA_VAR_HPP
#define JIAJIA_VAR_HPP

namespace jiajia{

    // var 是带着名字的 value
    // name 为 my::ustring
    // value 为 value 值

    template<typename VALUETYPE>
    class var{
    public:
        using nameType = my::ustring;
        using valueType = VALUETYPE;

    private:
        nameType mName;
        valueType mValue;

    public:
        var():mName(), mValue(){}

        var(const var & rhs):mName(rhs.mKey), mValue(rhs.mValue){}

        var(var && rhs): mName(std::move(rhs.mName)), mValue(std::move(rhs.mValue)){}

        var & operator=(const var & rhs){
            if(this == &rhs) return *this;

            mName = rhs.mName;
            mValue = rhs.mValue;

            return *this;
        }

        var & operator=(var && rhs){
            if(this == &rhs) return *this;

            mName = std::move(rhs.mName);
            mValue = std::move(rhs.mValue);

            return *this;
        }

        inline my::ustring & name(){
            return mName;
        }

        inline valueType & value(){
            return mValue;
        }

        bool toString(std::string & s){
            s.append(mName.toString()).append("=");
            bool flag = mValue.toString(s);
            return flag;
        }

        static int NameComp(var & lhs, const nameType & name){
            return my::ustring::comp(lhs.mName, name);
        }

        static void InitByName(var & lhs, const nameType & name){
            lhs.mName= name;
        }

        static int comp(const var & lhs, const var & rhs){
            return my::ustring::comp(lhs.name(), rhs.name());
        }
    };

    template<typename T>
    bool operator==(const var<T> & lhs, const var<T> & rhs){
        return my::ustring::comp(lhs.name(), rhs.name()) == 0;
    }
    
    template<typename T>
    bool operator!=(const var<T> & lhs, const var<T> & rhs){
        return my::ustring::comp(lhs.name(), rhs.name()) != 0;
    }
    
    template<typename T>
    bool operator>(const var<T> & lhs, const var<T> & rhs){
        return my::ustring::comp(lhs.name(), rhs.name()) > 0;
    }

    template<typename T>
    bool operator>=(const var<T> & lhs, const var<T> & rhs){
        return my::ustring::comp(lhs.name(), rhs.name()) >= 0;
    }

    template<typename T>
    bool operator<(const var<T> & lhs, const var<T> & rhs){
        return my::ustring::comp(lhs.name(), rhs.name()) < 0;
    }

    template<typename T>
    bool operator<=(const var<T> & lhs, const var<T> & rhs){
        return my::ustring::comp(lhs.name(), rhs.name()) <= 0;
    }
}

#endif
